package kyo;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * 菜单抽象类
 *
 * 封装菜单实现细节，抽象菜单条目信息及菜单业务逻辑
 *
 */
abstract public class Menu<I, D> {
    private ArrayList<Item<I, D>> list = new ArrayList<Item<I, D>>();
    // 提供接口由用户统一处理菜单条目操作
    private ItemRun iRun = null;
    //条目类通用传递参数
    private D itemData = null;
    // 菜单标题
    private I title = null;
    // 菜单层级标识
    private byte level = 0;

    public Menu() {
        this(null, null, null);
    }

    public Menu(I title) {
        this(title, null, null);
    }

    public Menu(I title, ItemRun iRun) {
        this(title, iRun, null);
    }

    public Menu(ItemRun iRun) {
        this(null, iRun, null);
    }

    public Menu(ItemRun iRun, D itemData) {
        this(null, iRun, itemData);
    }

    public Menu(I title, ItemRun iRun, D itemData) {
        set(title, iRun, itemData);
    }

    public Menu<I, D> set(I title, ItemRun iRun, D itemData) {
        setTitle(title);
        setRun(iRun);
        setData(itemData);
        return this;
    }

    public Menu<I, D> setRun(ItemRun iRun) {
        this.iRun = iRun;
        return this;
    }

    public Menu<I, D> setData(D itemData) {
        this.itemData = itemData;
        return this;
    }

    public Menu<I, D> setTitle(I title) {
        this.title = title;
        return this;
    }

    public Menu<I, D> setLevel(byte level) {
        this.level = level;
        return this;
    }

    public byte getLevel() {
        return level;
    }

    public Menu<I, D> add(Item<I, D> item) {
        if (item.isSubMenu()) {
            item.getSubMenu().setLevel((byte)(level + 1));
        }
        item.setId(list.size() + 1);
        if (!list.contains(item))
            list.add(item);
        return this;
    }

    public Menu<I, D> add(Item<I, D> [] item) {
        for (Item<I, D> i : item) {
            add(i);
        }
        return this;
    }

    public Menu<I, D> add(I info, ItemRun iRun, D rundata) {
        return add(new Item<I, D>(info, iRun, rundata));
    }

    public Menu<I, D> add(I info) {
        return add(info, iRun, itemData);
    }

    public Menu<I, D> add(I info, ItemRun iRun) {
        return add(info, iRun, itemData);
    }

    /** 根据下标删除条目对象 */
    public Menu<I, D> del(int index) {
        list.remove(index);
        return this;
    }

    /** 根据下标获取条目对象 */
    public Item<I, D> get(int index) {
        return list.get(index);
    }

    /** 根据下标更新条目对象 */
    public Menu<I, D> set(int index, Item<I, D> item) {
        list.set(index, item);
        return this;
    }

    /** 获取菜单条目个数 */
    public int getSize() {
        return list.size();
    }
    /** 显示菜单条目 */
    public void showItem(int index, I itemInfo) {
        System.out.println(itemInfo.toString());
    }

    /** 遍历菜单条目 */
    public void showList() {
        Iterator<Item<I, D>> it = list.iterator();
        showItem(0, title);        //显示标题
        int n = 0;
        // 遍历菜单条目显示
        while (it.hasNext()) {
            showItem(++n, it.next().getInfo());
        }
    }

    //子类重写此方法, 可实现自定义输入与输出格式
    public abstract boolean run();
}
